package iec104_master_connector

import (
	"fmt"
	"github.com/sirupsen/logrus"
	"go-iot-gateway/internal/channel"
	channel_define "go-iot-gateway/internal/channel/define"
	"go-iot-gateway/internal/conf_table"
	"go-iot-gateway/internal/conf_table/define"
	iec104_apdu "go-iot-gateway/pkg/iec104/apdu"
	iec104_client "go-iot-gateway/pkg/iec104/client"
	"strconv"
)

type Iec104MasterChannel struct {
	//ProtocolConf   map[int]define.Attr
	ChannelInfo    channel_define.ChannelInfo
	isClosed       bool
	channelManager *channel.ChannelManager
	iec104Client   *iec104_client.Iec104Client
	readTagList    []*conf_table_define.TagInfo //读点位
	writeTagList   []*conf_table_define.TagInfo //写点位
	logger         *logrus.Logger
}

func (i *Iec104MasterChannel) Open() {
	i.logger.Debug("启动104通道 ", i.ChannelInfo.Name)
	//TODO implement me
	//panic("implement me")
	i.isClosed = false
	i.ChannelInfo.SetStatus(channel_define.CONNECT_STATUS_CONNECTING, "")
	i.loadConfig()
	go func() { i.iec104Client.Connect() }()

}

func (i *Iec104MasterChannel) loadConfig() {
	//deviceConfInfos := conf_table.FindAllValidDeviceByChlId(i.ChannelInfo.ChlId)

	//conf_table.FindAllTagByDeviceId()

	tagConfInfos := conf_table.FindAllTagByChlId(i.ChannelInfo.ChlId)
	if len(tagConfInfos) == 0 {
		return
	}
	i.readTagList = make([]*conf_table_define.TagInfo, 0, 500)
	i.writeTagList = make([]*conf_table_define.TagInfo, 0, 30)

	for _, tag := range tagConfInfos {
		//过滤无效的设备
		if !tag.DeviceInfo.IsValid() {
			continue
		}

		//过滤不是整数地址的
		_, err := strconv.ParseInt(tag.Obj_addr, 10, 32)
		if err != nil {
			continue
			return
		}

		// 过滤异常的采集节点
		switch tag.Collect_type {
		case 1, 2, 3, 4:
			//正确的采集类型
		default:
			continue
		}

		//todo 按设备分组
		//todo 按读写类型分组
		//todo 按地址排序
		//todo 按四遥分组
		if tag.Tag_type == conf_table_define.TAG_TYPE_YX || tag.Tag_type == conf_table_define.TAG_TYPE_YC || tag.Tag_type == conf_table_define.TAG_TYPE_YM {
			i.readTagList = append(i.readTagList, tag)
		} else if tag.Tag_type == conf_table_define.TAG_TYPE_YT || tag.Tag_type == conf_table_define.TAG_TYPE_YK {
			i.writeTagList = append(i.writeTagList, tag)
		} else {
			panic("标签类型匹配不到")
		}
	}
}

func (i *Iec104MasterChannel) Close() {
	i.isClosed = true
	if i.iec104Client != nil {
		i.iec104Client.DisConnect()
	}
	i.ChannelInfo.SetStatus(channel_define.CONNECT_STATUS_CLOSED, "主动关闭")
}

func (i *Iec104MasterChannel) Info() channel_define.ChannelInfo {
	return i.ChannelInfo
}

func (i *Iec104MasterChannel) onConnectionLost() {
	//iec104 会自动重连
	i.ChannelInfo.SetStatus(channel_define.CONNECT_STATUS_CONNECTING, "")
}

func (i *Iec104MasterChannel) onConnect() {
	i.ChannelInfo.SetStatus(channel_define.CONNECT_STATUS_CONNECTED, "")
}

func (i *Iec104MasterChannel) onMessageHandler(apdu *iec104_apdu.APDU) {
	//保处理 i 帧的数据包
	switch apdu.Frame.Type() {
	case iec104_apdu.FrameTypeI:
	default:
		//不处理其他类型的帧
		return
	}

	//获取公共地址
	//pubAddr := apdu.ASDU.Coa

	/**
	从站发送
	68 0e 02 00 02 00 01 01 01 00 01 00 00 00 00 00
	起始字节=68 数据单元长度(APDU)=14 I格式帧 发送序号(NS)=1 接收序号(NR)=1 TI= 1 VSQ=01 SQ=0 INFONUM=1 COT= 0001 T=0 PN=0 CAUSE =1 COA =1 M_SP_NA_1
	单点遥信变位          肯定认可    周期、循环
	 变位有效 IV=0  当前值 NT=0  未被取代 SB=0  未被封锁 BL=0 点号=0 分
	*/
	//todo 处理数据
	fmt.Printf("采集到数据了 %+v", apdu)
}
